import {BookmarkRange, Dictionary} from "./types/Types";
import {addExtendAgentToUrl, buildFullUrl, safeToString} from "./function/CommonUtils";
import {AbstractWebOffice} from "./AbstractWebOffice";

export class ZhuoZhengWebOffice extends AbstractWebOffice {
    _ready: boolean = false;
    private static _pluginType: string = 'pageoffice';

    constructor(wrapperId: string, public options: Dictionary) {
        super(wrapperId, options);
        const self = this;
        setTimeout(()=>{
            if (!self.pluginObj().OfficeVendor)
                self._ready = true;
        },200);
        window._pageofficedocumentopened = function () {
            self._officeApp = self.pluginObj().Document.Application;
            setTimeout(function () {
                self.pluginObj().JsFunction_OnWordDataRegionClick = '';
                self._initDocument().then(function (result) {
                    if (result.errorCode == '0')
                        self._ready = true;
                }, function (error) {
                    console.error(error.errorMessage);
                    throw new Error(error.errorMessage);
                });
            });
        };
    }

    protected _createObjectHtml(objId: string): string {
        return this.options.pluginHtml;
    }

    private _initDocument(): Promise<any> {
        const self = this;
        return new Promise(function (resolve, reject) {
            try {
                const openMode = self.options.openMode;
                if (self.options.userName)
                    self.officeApp().UserName = self.options.userName;
                try {
                    self._publicDocumentInitialize();
                } catch (e) {
                    reject({errorCode: '-1', errorMessage: e});
                }
                if (self.pluginObj().DataRegionList) {
                    self.pluginObj().DataRegionList.Refresh();
                }
                if (self.options.jsFunction_OnWordDataRegionClick && (openMode == "docNormalEdit" || openMode == "docSubmitForm" || openMode == "docAdmin")) {
                    window['_defaultOnWordDataRegion'] = function () {
                        self._onWordWpsSelChange(self.officeApp().Selection);
                    }
                    self.pluginObj().JsFunction_OnWordDataRegionClick = '_defaultOnWordDataRegion()';
                }
                resolve({errorCode: '0', errorMessage: 'OK'});
            } catch (e) {
                reject({errorCode: '-1', errorMessage: e});
            }
            // },defer.reject);

        });

    }

    protected _initDocumentFields() {
        let fields: Dictionary<BookmarkRange> = {};
        if (this.options.document && this.options.document.bookmarkRangeDict) {
            fields = this.options.document.bookmarkRangeDict;
        }
        const bookmarks = this.activeDocument().Bookmarks;
        const bookmarkCount = bookmarks.Count;
        for (let i = 1; i <= bookmarkCount; i++) {
            const bookmark = bookmarks.Item(i);
            if (!bookmark)
                continue;
            const bookmarkName = bookmark.Name;
            const bookmarkCache = this._cacheBookmarkRange(bookmarkName, bookmark);
            const noPrefixName=bookmarkName.substring(3);
            this._lowerCaseNameToOriginMap[noPrefixName.toLowerCase()]=noPrefixName;
            this._bookmarkRange[noPrefixName.toLowerCase()]=bookmarkCache;
            if (fields[bookmarkName]||fields[noPrefixName]) {
                this._initEditors(fields[bookmarkName] || fields[noPrefixName]);
            }
        }

    }

    private _getCommandBar(barName: string) {
        return this.activeDocument().CommandBars.Item(barName);
    }

    private _getControlByName(barName: string, controlName: string) {
        const commandBar = this._getCommandBar(barName);
        if (commandBar == null || commandBar == undefined)
            return null;
        return commandBar.Controls.Item(controlName);
    }

    private fullScreen() {
        this.officeApp().FullScreen();
    }


    protected _bookmarkNameAdapter(bookmarkName: string) {
        return bookmarkName.toLowerCase().indexOf("po_") == 0 ? bookmarkName : "PO_" + bookmarkName;
    }


    public deleteBookmark(name: string): void {
        super.deleteBookmark(name);
        const that = this;
        delete that._bookmarkRange[safeToString(name).toLowerCase()];
        if (that.pluginObj().DataRegionList)
            that.pluginObj().DataRegionList.Refresh();
    }


    public getBookmarkValue(bookmarkName: string): string | undefined {
        const that = this;
        let result: string = "";
        const poName = that._bookmarkNameAdapter(bookmarkName);
        const dataRegionList = that.pluginObj().DataRegionList;
        if (dataRegionList && dataRegionList.DataRegionByNameExists(poName)) {
            result = dataRegionList.GetDataRegionByName(poName).Value;//获取书签的值
        }
        result = safeToString(result);
        result = result.replace(/\x07$/g, "").replace(/\x0d$/g, "");
        return result;

    }

    public enableToolbars(enable: boolean = true) {
        this.options.officeToolbars = enable;
        this.pluginObj().OfficeToolbars = enable;
    }


    public print(): void {
        const that = this;
        that.pluginObj().ShowDialog(4);

    }

    public importFile(): Promise<any> {
        const that = this;
        return new Promise<any>(function (resolve, reject) {
            try {
                that.pluginObj().WordImportDialog();
                resolve({errorCode: '0', errorMessage: 'OK', result: true});
            } catch (e) {
                reject({errorCode: '-1', errorMessage: e, result: false});
            }
        })

    }

    public printPreview() {
        this.pluginObj().PrintPreview();
    }

    public closePrintPreview() {
        this.activeDocument().ClosePrintPreview();
    }

    public openRemoteFile(fileUrl: string, readOnly: boolean): Promise<any> {
        const that = this;
        return new Promise<any>(function (resolve, reject) {
            try {
                that._ready = false;
                that._officeApp = null;
                that.pluginObj().WebOpen(fileUrl, "docNormalEdit", that.options.userName);
                resolve({errorCode: '0', errorMessage: 'OK', result: true});
            } catch (e) {
                reject({errorCode: '-1', errorMessage: e, result: false});
            }

        })

    }

    public showRevisions(show: boolean = true): void {
        this.pluginObj().ShowRevisions = show;

    }

    public isDirty() {
        return !this.activeDocument().Saved;
    }

    public saveAs(fileName?: string) {
        this.pluginObj().ShowDialog(3);
    }

    public saveToUrl(tempUrl?: string): Promise<any> {
        const self = this;
        const url = tempUrl || self.options.saveFilePage;
        return new Promise(function (resolve, reject) {
            let unprotect = false;
            if (self._protectionType > -1) {
                unprotect = true;
                self.activeDocument().Unprotect(self._protectPass);
            }
            if (self._protectionType == 3) {
                self._deleteAllEditors();
            }
            self.pluginObj().SaveFilePage = addExtendAgentToUrl(url, ZhuoZhengWebOffice._pluginType);
            self.pluginObj().WebSave();
            const resultStr = self.pluginObj().CustomSaveResult;
            if (self._protectionType == 3) {
                self._recoveryAllEditors();
            }
            if (unprotect && self._protectionType > -1)
                self.activeDocument().Protect(self._protectionType, true, self._protectPass);
            resolve({errorCode: "0", result: resultStr, errorMessage: "OK"});
        });
    }

    public getAllBookmarkValue(): Object {
        const that = this;
        const fieldData: Dictionary = {};
        for (let bookmarkName in that._bookmarkRange) {
            const originName=this._lowerCaseNameToOriginMap[bookmarkName]||bookmarkName;
            const value = that.getBookmarkValue(originName);
            fieldData[originName] = value;
            if(originName.toLowerCase().startsWith("po_")){
                fieldData[originName.substring(3)] = value;
            }
        }
        if (that.pluginObj().DataRegionList) {
            const dataRegionList = that.pluginObj().DataRegionList;
            dataRegionList.Refresh();
            const dataRegionCount = dataRegionList.Count;
            for (let i = 0; i < dataRegionCount; i++) {
                const item = dataRegionList.Item(i);
                if (!fieldData[item.Name]||!fieldData[item.Name.substring(3)]) {
                    let value = item.Value;
                    if (value) {
                        value = value.replace(/[\s|\r]*\x07$/g, "");
                    }
                    fieldData[item.Name] = value;
                    fieldData[item.Name.substring(3)] = value;
                }
            }
        }
        return fieldData;
    }


    createFile(): Promise<any> {
        return Promise.resolve({errorCode: '0', errorMessage: 'OK', result: this.officeApp().Documents.Add()});
    }


    openLocalFile(filePath: string, readOnly: boolean): Promise<any> {
        return Promise.resolve(undefined);
    }

    runMacro(method: string, command?: string): any {
        if (!this.activeDocument().VBProject)
            return 0;
        return this.pluginObj().RunMacro(method, command);
    }

    public insertDocumentFromUrl(documentUrl: string): Promise<boolean> {
        const that = this;
        return new Promise(function (resolve) {
            that.pluginObj().InsertDocumentFromURL(buildFullUrl(documentUrl));
            resolve(true);
        });
    }

}